#include "http_parser.hpp"

using namespace mms;

boost::asio::awaitable<int32_t> HttpParser::read(const std::string_view& buf)
{
    switch (state_)
    {
    case HTTP_STATE_WAIT_REQUEST_LINE:{
            http_req_ = std::make_shared<HttpRequest>();
            auto pos = buf.find("\r\n");
            if(pos != std::string::npos){
                if(!http_req_->parse_request_line(buf.data(),pos)){
                    state_ = HTTP_STATE_REQUEST_ERROR;
                    co_return -1;
                }else{
                    state_ = HTTP_STATE_WAIT_HEADER;
                    co_return pos + 2;
                }
            }else{
                co_return 0;
            }
            break;
        }
        case HTTP_STATE_WAIT_HEADER:{
            auto pos = buf.find("\r\n");
            if(pos != std::string::npos){
                if(pos == 0){ // 最后的\r\n
                    // content-len 得到长度
                    if(http_req_->get_method() == GET){
                        state_ = HTTP_STATE_WAIT_REQUEST_LINE;
                        co_await req_cb_(http_req_);
                        co_return pos + 2;
                    }else if(http_req_->get_method() == POST){
                        state_ = HTTP_STATE_REQUEST_BODY;
                        co_return pos + 2;
                    }
                }else {
                    if(!http_req_->parse_header(buf.data(), pos)){
                        state_ = HTTP_STATE_REQUEST_ERROR;
                        co_return -2;
                    }else {
                        state_ = HTTP_STATE_WAIT_HEADER;
                        co_return pos + 2;
                    }

                }
            }
            break;
        }
        case HTTP_STATE_REQUEST_BODY:{
            try{
                if(!http_req_->parse_body(buf.data(), buf.size())){
                    state_ = HTTP_STATE_REQUEST_ERROR;
                    co_return -5;
                }
                co_await req_cb_(std::move(http_req_));
                state_ = HTTP_STATE_WAIT_REQUEST_LINE;
                co_return buf.size();
            }catch(std::exception& e){
                co_return -4;
            }
        }
      
    
    default:{
        co_return 0;
    }
       
    }
    co_return 0;
}

void HttpParser::on_http_request(const std::function<boost::asio::awaitable<void>(std::shared_ptr<HttpRequest>)>& cb) {
    req_cb_ = cb;
}

HttpParser::~HttpParser() {
    spdlog::debug("destroy HttpParser");
}